import json
from django.http import JsonResponse
from django.views.generic import View
from ..utils.literUtils import handle_serializer_error, emptyValue
from django.db.models import Q
from ..models.Keyword import Keyword
from ..models.GlobalTables import KeywordType
from django.core.paginator import Paginator
from utils.encryptionAndDecryptionUtil import get_useraccount_from_request
from datetime import datetime
import traceback
from control.models.User import User
from ..serializers.keywordListSerializer import KeywordDetailListQuerySerializer, KeywordDetailListSerializer, TagListQuerySerializer, TagListSerializer, SubjectListQuerySerializer, SubjectListSerializer, KeywordListQuerySerializer, KeywordListSerializer
from ..serializers.keywordInfoSerializer import KeywordDetailCreateSerializer, KeywordDetailInfoSerializer

class KeywordDetailView(View):
    def get(self, request):
        res = {"code": 400, "message": "", "data": None}
        try:
            data = request.GET
            query_list_serializer = KeywordDetailListQuerySerializer(data=data)
            data_valid = query_list_serializer.is_valid()
            if not data_valid:
                res["code"] = 400
                res["message"] = "参数错误：" + \
                    handle_serializer_error(
                        errors=query_list_serializer.errors)
                return JsonResponse(res)
            data = query_list_serializer.validated_data
            keywords = Keyword.objects.all().order_by('-create_date')
            query = Q()
            if "k" in data and data["k"] != "":
                query &= Q(k__icontains=data["k"])
            if "v" in data and data["v"] != "":
                query &= Q(v__icontains=data["v"])
            if 'kt' in data and len(data['kt']) != 0:
                keyword_type_list = [x['[0]'] for x in data['kt']]
                query &= Q(kt_id__in=keyword_type_list)

            order_list_combined = []
            prop_list = data.get('sort_prop', '').split(
                ',') if data.get('sort_prop') else []
            order_list = data.get('sort_order', '').split(
                ',') if data.get('sort_order') else []
            if len(prop_list) != len(order_list):
                res["code"] = 400
                res["message"] = "排序参数错误"
                return JsonResponse(res)
            for i in range(len(prop_list)):
                for prop, order in zip(prop_list, order_list):
                    if order.lower() == 'ascending':
                        order_list_combined.append(prop)
                    elif order.lower() == 'descending':
                        order_list_combined.append(f'-{prop}')
            if len(query) != 0:
                keywords = keywords.filter(query)


            if len(order_list_combined) != 0:
                keywords = keywords.order_by(*order_list_combined)
            total_count = keywords.count()
            res_data = {}
            if "page_size" in data:
                page_size = data["page_size"]
                current_page = data["current_page"]
                paginator = Paginator(keywords, page_size)
                if current_page > paginator.num_pages:
                    current_page = paginator.num_pages
                page_obj = paginator.get_page(current_page)
                res_data["current_page"] = current_page
                res_data["page_size"] = page_size
                res_data["total_count"] = total_count
                keyword_list_serializer = KeywordDetailListSerializer(
                    page_obj, many=True)
                res_data["objects"] = keyword_list_serializer.data
                res["code"] = 200
                res["message"] = "查询成功"
                res["data"] = res_data
                return JsonResponse(res)
            res_data["total_count"] = total_count
            keyword_list_serializer = KeywordDetailListSerializer(
                keywords, many=True)
            res_data["objects"] = keyword_list_serializer.data
            res["code"] = 200
            res["message"] = "查询成功"
            res["data"] = res_data
            return JsonResponse(res)
        except Exception as e:
            traceback.print_exc()
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)
    
    def post(self, request):
        res = {"code": 400, "message": "", "data": None}
        try:
            user_name = get_useraccount_from_request(request=request)
            u = User.objects.filter(user_account=user_name)[0]
            # print(request.body)
            data = json.loads(request.body)
            data['kt'] = KeywordType.objects.filter(name='unknown')[0].uuid if emptyValue(data['kt']) else data['kt']
                    
            add_serializer = KeywordDetailCreateSerializer(data=data)
            data_valid = add_serializer.is_valid()
            if not data_valid:
                print(add_serializer.errors)
                serial_errors = handle_serializer_error(
                    errors=add_serializer.errors)
                res["code"] = 400
                res["message"] = "参数错误：\n" + serial_errors
                return JsonResponse(res)
            data = add_serializer.validated_data
            data["creator"] = u
            data["last_editor"] = u
            Keyword.objects.create(**data)

            res["code"] = 200
            res["message"] = "新建成功"
            res["data"] = None
        except Exception as e:
            traceback.print_exc()
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)
    

class KeywordDetailInfoView(View):
    def delete(self, request, id):
        res = {"code": 400, "message": "", "data": None}
        try:
            user_name = get_useraccount_from_request(request=request)
            kw = Keyword.objects.get(uuid=id)
            if kw is None:
                res["code"] = 400
                res["message"] = "该条目不存在"
                return JsonResponse(res)
            
            if len(kw.literature_set.all()) > 0:
                res["code"] = 400
                res["message"] = "删除失败：仍有其他文献引用该关键词"
                return JsonResponse(res)
            if len(kw.author_set.all()) > 0:
                res["code"] = 400
                res["message"] = "删除失败：仍有其他作者引用该关键词"
                return JsonResponse(res)
            if len(kw.publication_set.all()) > 0:
                res["code"] = 400
                res["message"] = "删除失败：仍有其他出版物引用该关键词"
                return JsonResponse(res)
            
            kw.delete()
            res["code"] = 200
            res["message"] = "删除成功"
            res["data"] = None
        except Exception as e:
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)
    
    def get(self, request, id):
        res = {"code": 400, "message": "", "data": None}
        try:
            kw = Keyword.objects.get(uuid=id)
            kw = KeywordDetailInfoSerializer(kw).data
            # print(kw)
            res["code"] = 200
            res["message"] = "查询成功"
            res["data"] = kw
        except Exception as e:
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)
    
    def put(self, request, id):
        res = {"code": 400, "message": "", "data": None}
        try:
            user_name = get_useraccount_from_request(request=request)
            u = User.objects.filter(user_account=user_name)[0]
            data = json.loads(request.body)
            data['kt'] = KeywordType.objects.filter(name='unknown')[0].uuid if emptyValue(data['kt']) else data['kt']      
            
            kw = Keyword.objects.get(uuid=id)
            
            if kw.kt.name == "Keyword" and len(kw.literature_set.all()) > 0:
                res["code"] = 400
                res["message"] = "仍有其他文献引用该关键词，无法编辑当前条目的关键词类别"
                return JsonResponse(res)  
            
            if kw.kt.name == "Tag" and len(kw.author_set.all()) > 0:
                res["code"] = 400
                res["message"] = "仍有其他作者引用该标签，无法编辑当前条目的关键词类别"
                return JsonResponse(res)  
            
            if kw.kt.name == "Subject" and len(kw.publication_set.all()) > 0:
                res["code"] = 400
                res["message"] = "仍有其他出版物引用该主题，无法编辑当前条目的关键词类别"
                return JsonResponse(res)  
            
            modify_serializer = KeywordDetailCreateSerializer(instance=kw, data=data)
            data_valid = modify_serializer.is_valid()
            if not data_valid:
                res["code"] = 400
                res["message"] = "参数错误：" + \
                    handle_serializer_error(
                        errors=modify_serializer.errors)
                return JsonResponse(res)
            data = modify_serializer.validated_data
            data["last_editor"] = u
            
            modify_serializer.save()
            res["code"] = 200
            res["message"] = "编辑成功"
            res["data"] = None
        except Exception as e:
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
            print(e)
        return JsonResponse(res)
    
    
class KeywordView(View):
    def get(self, request):
        res = {"code": 400, "message": "", "data": None}
        try:
            data = request.GET
            query_list_serializer = KeywordListQuerySerializer(data=data)
            data_valid = query_list_serializer.is_valid()
            if not data_valid:
                res["code"] = 400
                res["message"] = "参数错误：" + \
                    handle_serializer_error(
                        errors=query_list_serializer.errors)
                return JsonResponse(res)
            data = query_list_serializer.validated_data
            keyword_type = KeywordType.objects.filter(name="Keyword")[0]
            keywords = Keyword.objects.filter(kt=keyword_type).all().order_by('create_date')
            query = Q()
            if "k" in data and data["k"] != "":
                query &= Q(k__icontains=data["k"])
            if "v" in data and data["v"] != "":
                query &= Q(v__icontains=data["v"])

            if len(query) != 0:
                keywords = keywords.filter(query)

            total_count = keywords.count()
            res_data = {}
            res_data["total_count"] = total_count
            keyword_list_serializer = KeywordListSerializer(
                keywords, many=True)
            res_data["objects"] = keyword_list_serializer.data
            res["code"] = 200
            res["message"] = "查询成功"
            res["data"] = res_data
            return JsonResponse(res)
        except Exception as e:
            traceback.print_exc()
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)    
    
    
class TagView(View):
    def get(self, request):
        res = {"code": 400, "message": "", "data": None}
        try:
            data = request.GET
            query_list_serializer = TagListQuerySerializer(data=data)
            data_valid = query_list_serializer.is_valid()
            if not data_valid:
                res["code"] = 400
                res["message"] = "参数错误：" + \
                    handle_serializer_error(
                        errors=query_list_serializer.errors)
                return JsonResponse(res)
            data = query_list_serializer.validated_data
            tag_type = KeywordType.objects.filter(name="Tag")[0]
            tags = Keyword.objects.filter(kt=tag_type).all().order_by('create_date')
            query = Q()
            if "k" in data and data["k"] != "":
                query &= Q(k__icontains=data["k"])
            if "v" in data and data["v"] != "":
                query &= Q(v__icontains=data["v"])

            if len(query) != 0:
                tags = tags.filter(query)

            total_count = tags.count()
            res_data = {}
            res_data["total_count"] = total_count
            tag_list_serializer = TagListSerializer(
                tags, many=True)
            res_data["objects"] = tag_list_serializer.data
            res["code"] = 200
            res["message"] = "查询成功"
            res["data"] = res_data
            return JsonResponse(res)
        except Exception as e:
            traceback.print_exc()
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)
    
    
class SubjectView(View):
    def get(self, request):
        res = {"code": 400, "message": "", "data": None}
        try:
            data = request.GET
            query_list_serializer = SubjectListQuerySerializer(data=data)
            data_valid = query_list_serializer.is_valid()
            if not data_valid:
                res["code"] = 400
                res["message"] = "参数错误：" + \
                    handle_serializer_error(
                        errors=query_list_serializer.errors)
                return JsonResponse(res)
            data = query_list_serializer.validated_data
            subject_type = KeywordType.objects.filter(name="Subject")[0]
            subjects = Keyword.objects.filter(kt=subject_type).all().order_by('create_date')
            query = Q()
            if "k" in data and data["k"] != "":
                query &= Q(k__icontains=data["k"])
            if "v" in data and data["v"] != "":
                query &= Q(v__icontains=data["v"])

            if len(query) != 0:
                subjects = subjects.filter(query)

            total_count = subjects.count()
            res_data = {}
            res_data["total_count"] = total_count
            subject_list_serializer = SubjectListSerializer(
                subjects, many=True)
            res_data["objects"] = subject_list_serializer.data
            res["code"] = 200
            res["message"] = "查询成功"
            res["data"] = res_data
            return JsonResponse(res)
        except Exception as e:
            traceback.print_exc()
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)